package org.bdware.registry.examples;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.log4j.Logger;
import org.bdware.doip.core.crypto.GlobalCertifications;
import org.bdware.irp.stateinfo.DoipServiceStateInfo;
import org.bdware.doip.core.utils.GlobalConfigurations;
import org.bdware.doip.endpoint.doipServer.*;
import org.bdware.irp.client.GlobalIrpClient;
import org.bdware.doip.implementation.*;
import org.bdware.registry.DoipServiceConfig;
import org.bdware.registry.handler.SimpleRegistryHandler;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;
import java.util.List;

public class SimpleRegistryMain {

    static Logger logger = Logger.getLogger(SimpleRegistryMain.class);
    /**
     * DOIP Service Information
     */
    public static String listeners = "[{\"url\":\"tcp://127.0.0.1:1720\",\"protocolVersion\":\"2.1\",\"messageFormat\":\"packet\"}]";
    public static String repoID = "86.5000.470/doip.localTcpRegistry";
    public static String serviceDescription = "test local TCP Repository";
    public static String serviceName = "TestTCPRegistry";
    public static String IRSAddress = "http://127.0.0.1:10001/";
    public static String type;

    static String confPath = "default_regi.json";
    static String dbPath = "metadataDB1";

    public static void main(String[] args) throws Exception {

        DoipServiceConfig doipServiceConfig = DoipServiceConfig.loadFromConfigFile(confPath);

        DoipServiceInfo info;
        GlobalConfigurations.IRSAddress = IRSAddress;
        if(doipServiceConfig != null && doipServiceConfig.listeners != null && !doipServiceConfig.listeners.equals("")) {
            if (doipServiceConfig.IRSAddress != null) GlobalConfigurations.IRSAddress = doipServiceConfig.IRSAddress;
            if (doipServiceConfig.userID != null) GlobalConfigurations.userID = doipServiceConfig.userID;
            if (doipServiceConfig.jwkPath != null) GlobalConfigurations.JWKPath = doipServiceConfig.jwkPath;
            if (doipServiceConfig.jksPath != null) GlobalConfigurations.JKSPath = doipServiceConfig.jksPath;
            if (doipServiceConfig.jksPassword != null) GlobalConfigurations.JKSPassword = doipServiceConfig.jksPassword;
        } else {
            logger.info("cannot find config file, using default config");
            doipServiceConfig = DoipServiceConfig.createDefaultConfig();
        }

        /** if you prefer use elastic search as search backend, after you deployed es, config the indexer as following:
        String elasticSearchUrl = "http://localhost:9002";  //change the ip and port according to your es configuration
        String elasticSearchIndexName = "test";
        DoIndexer indexer = new DoIndexerESImpl(elasticSearchIndexName, elasticSearchUrl);
         */

        DoIndexer indexer = new DoIndexerLuceneImpl("index");
        DoStorage storage = new DoStorageRocksDBImpl(dbPath);

        try {
            init();
            info = new DoipServiceInfo(
                    doipServiceConfig.repoID,
                    doipServiceConfig.userID,
                    doipServiceConfig.type,
                    new Gson().fromJson(doipServiceConfig.listeners, new TypeToken<List<DoipListenerInfo>>(){}.getType()));
            info.serviceName = doipServiceConfig.serviceName;
            info.serviceDescription = doipServiceConfig.serviceDescription;


            DoipServiceStateInfo repoHR = info.toServiceHandleRecord();
            logger.debug(new Gson().toJson(repoHR));
            if(repoHR.identifier == null || repoHR.identifier.equals("")){
                String newHandle = GlobalIrpClient.getGlobalClient().register(repoHR);
                logger.info("[HandleService] response from LHS: " + newHandle);
                doipServiceConfig.repoID = info.id = newHandle;
            }else{
                String LHSResp = GlobalIrpClient.getGlobalClient().reRegister(repoHR);
                logger.info("[HandleService] response from LHS: " + LHSResp);
            }

            DoipServer server = DoipServerImpl.createDoipServer(info);
            RegistryHandler registryHandler = new SimpleRegistryHandler(info,storage,indexer);
            server.setRepositoryHandler(registryHandler);
            server.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void init() throws Exception {
        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }

        GlobalCertifications.loadKeysFromJWK(GlobalConfigurations.JWKPath);

        GlobalIrpClient.useInternalIrpClient(GlobalCertifications.jwKeyPair
                , GlobalConfigurations.userID
                , GlobalConfigurations.IRSAddress);


    }
}
